package javacommon.filter;

import java.io.IOException;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class CheckSessionFilter implements Filter {
	static Log log = LogFactory.getLog(CheckSessionFilter.class);

	protected FilterConfig filterConfig;

	private String firstPage;

	private String sessionName;

	private String checkPattern;

	private String exceptPattern;

	private String ctx;

	private String patternDelims;

	Pattern checkP[];

	Pattern exceptP[];

	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		firstPage = filterConfig.getInitParameter("firstPage");
		sessionName = filterConfig.getInitParameter("sessionName");
		checkPattern = filterConfig.getInitParameter("checkPattern");
		exceptPattern = filterConfig.getInitParameter("exceptPattern");
		patternDelims = filterConfig.getInitParameter("patternDelims");
		if (empty(patternDelims))
			patternDelims = ",";
		if (!empty(checkPattern))
			checkP = makePattern(checkPattern);
		if (!empty(exceptPattern))
			exceptP = makePattern(exceptPattern);
		if (empty(sessionName)) {
			sessionName = "SessionUser";
		}
		if (empty(firstPage)) {
			firstPage = "/index.jsp";
		}
	}

	private Pattern[] makePattern(String pattern) {
		String[] str = pattern.split(patternDelims);
		Pattern[] p = new Pattern[str.length];
		for (int i = 0; i < str.length; i++) {
			p[i] = Pattern.compile(str[i]);
		}
		return p;
	}

	private String path(String str) {
		return str.replaceFirst("^[/\\\\]", "").replaceFirst("[/\\\\]$", "");
	}

	private boolean empty(String str) {
		return str == null || str.equals("");
	}

	private boolean check(String str) {
		if (checkP == null)
			return true;
		for (int i = 0; i < checkP.length; i++) {
			if (checkP[i].matcher(str).find())
				return true;
		}
		return false;
	}

	private boolean except(String str) {
		if (exceptP == null)
			return false;
		for (int i = 0; i < exceptP.length; i++) {
			if (exceptP[i].matcher(str).find())
				return true;
		}
		return false;
	}

	public void doFilter(ServletRequest srequest, ServletResponse sresponse,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) srequest;
		HttpServletResponse response = (HttpServletResponse) sresponse;
		String url = path(request.getRequestURI());
		if (ctx == null) {
			ctx = path(request.getContextPath());
		}
		url = url.replaceFirst(ctx, "");
		if (!url.startsWith("/")) {
			url = "/" + url;
		}
		if (check(url) && !except(url)) {
			Object user = (Object)request.getSession().getAttribute(sessionName);
			log.debug("CheckSessionFilter : " + user);
			if (user==null) {
				response.sendRedirect(request.getContextPath() + firstPage);
				return;
			}
		}
		chain.doFilter(request, response);
	}

	public void destroy() {
		this.filterConfig = null;
	}

}
